package io.github.cubelitblade.librarymanagementbackend.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.github.cubelitblade.librarymanagementbackend.entity.FavoriteRecord;
import io.github.cubelitblade.librarymanagementbackend.entity.FavoriteRecordView;
import io.github.cubelitblade.librarymanagementbackend.exception.BusinessException;
import io.github.cubelitblade.librarymanagementbackend.mapper.FavoriteMapper;
import io.github.cubelitblade.librarymanagementbackend.mapper.FavoriteViewMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.util.List;

@Service
public class FavoriteService extends ServiceImpl<FavoriteMapper, FavoriteRecord> {
    private final FavoriteViewMapper favoriteViewMapper;

    FavoriteService(FavoriteViewMapper favoriteViewMapper) {
        this.favoriteViewMapper = favoriteViewMapper;
    }

    /**
     * 查询指定用户是否收藏了指定图书。
     *
     * @param userId 用户ID。
     * @param bookId 图书ID。
     * @return 如果存在 {@code active} 为 {@code true} 的记录，则返回 {@code true} ；否则返回 {@code false} 。
     */
    public boolean isFavorite(Integer userId, Integer bookId) {
        LambdaQueryWrapper<FavoriteRecord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FavoriteRecord::getUserId, userId).eq(FavoriteRecord::getBookId, bookId).eq(FavoriteRecord::getActive, true);
        return getOne(queryWrapper) != null;
    }

    /**
     * 将指定图书添加到指定用户的收藏夹。
     * <p>如果不存在此记录，则新增此记录；如果存在 {@code active} 为 {@code false} 的记录，则将其设为 {@code true}，并更新
     * {@code createTime}。</p>
     *
     * @param userId 用户ID。
     * @param bookId 图书ID。
     * @return 成功新增或更新记录时，返回表示此记录的实体。
     * @throws BusinessException 当存在 {@code active} 为 {@code true} 的记录或数据库操作失败时。
     */
    @Transactional
    public FavoriteRecord addToFavorites(Integer userId, Integer bookId) {
        LambdaQueryWrapper<FavoriteRecord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FavoriteRecord::getUserId, userId).eq(FavoriteRecord::getBookId, bookId);
        FavoriteRecord favoriteRecord = getOne(queryWrapper);

        if (favoriteRecord != null) {
            if (favoriteRecord.getActive()) {
                throw BusinessException.favoriteRecordStatusConflict();
            } else {
                favoriteRecord.setCreateTime(LocalDate.now());
                favoriteRecord.setActive(true);
                if (!this.updateById(favoriteRecord)){
                    throw BusinessException.databaseError();
                }
            }
        } else {
            favoriteRecord = new FavoriteRecord(
                    null,
                    userId,
                    bookId,
                    LocalDate.now(),
                    true
            );

            if (!this.save(favoriteRecord)){
                throw BusinessException.databaseError();
            }
        }
        return favoriteRecord;
    }

    /**
     * 移除指定ID的收藏记录。
     * <p>实际上执行软删除，在数据库中将 {@code active} 字段设置为 {@code false}。视图不展示 {@code active} 为 {@code false} 的记录。</p>
     *
     * @param favoriteRecordId 收藏记录的ID。
     * @throws BusinessException 当记录不存在，记录的 {@code active} 为 {@code false} 或数据库操作失败时。
     */
    public void removeFromFavorites(Integer favoriteRecordId) {
        FavoriteRecord favoriteRecord = getById(favoriteRecordId);
        if (favoriteRecord == null) {
            throw BusinessException.favoriteRecordNotFound();
        }

        if (!favoriteRecord.getActive()) {
            throw BusinessException.favoriteRecordStatusConflict();
        }

        favoriteRecord.setActive(false);
        if (!this.updateById(favoriteRecord)) {
            throw BusinessException.databaseError();
        }
    }

    /**
     * 获取用户的收藏列表。
     *
     * @param userId 用户ID。
     * @return 用户的收藏列表。
     */
    public List<FavoriteRecordView> listFavorites(Integer userId) {
        LambdaQueryWrapper<FavoriteRecordView> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FavoriteRecordView::getUserId, userId);
        return favoriteViewMapper.selectList(queryWrapper);
    }

    /**
     * 获取指定用户对指定图书收藏记录。
     *
     * @param userId 用户ID。
     * @param bookId 图书ID。
     * @return 如果存在 {@code active} 为 {@code true} 的收藏记录，则返回此记录。
     */
    public FavoriteRecordView getFavorite(Integer userId, Integer bookId) {
        LambdaQueryWrapper<FavoriteRecordView> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FavoriteRecordView::getUserId, userId).eq(FavoriteRecordView::getBookId, bookId);
        return favoriteViewMapper.selectOne(queryWrapper);
    }

    /**
     * 更改记录的 {@code active} 字段。
     *
     * @param favoriteRecordId 收藏记录的ID。
     * @return 更新后此记录的 {@code active} 字段的值。
     * @throws BusinessException 当记录不存在或数据库操作失败时。
     */
    public Boolean toggleFavoriteActive(Integer favoriteRecordId) {
        FavoriteRecord favoriteRecord = getById(favoriteRecordId);
        if (favoriteRecord == null) {
            throw BusinessException.favoriteRecordNotFound();
        }

        favoriteRecord.setActive(!favoriteRecord.getActive());
        if (!this.updateById(favoriteRecord)) {
            throw BusinessException.databaseError();
        }
        return favoriteRecord.getActive();
    }

    public Long countFavorites(Integer userId) {
        LambdaQueryWrapper<FavoriteRecordView> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FavoriteRecordView::getUserId, userId);
        return favoriteViewMapper.selectCount(queryWrapper);
    }
}
